import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox

import pandas
import pandas as pd
import os
import sys
import json
import string
import random
from copy import deepcopy
# 定义全局变量 excel
df = None
directory = None
default_outJson_text = "{2} | {3} \n {4} ❤{5} \n 关键词【{6}】\n 技能【{7}】 \n ▧水晶【{8}】 \n 词条分类【{9}】 \n 知识故事【{10}】"
backURLTemplate = "http://qungz.photo.store.qq.com/qun-qungz/V505EoQi07yWaA0iIp1X1kLVHM1W3aKN/V5bCQAxMjExNDc4MTX*sN9mR5MiNQ!!/800?w5=1346&h5=2055&rf=viewer_421"
non_empty_columns = None

def generate_random_string(length=6):
    # 定义字符集，包括大写字母和数字
    characters = string.ascii_lowercase + string.digits

    # 使用random.choices()从字符集中随机选择length个字符
    random_string = ''.join(random.choices(characters, k=length))

    return random_string
def select_excel_file():
    global df
    global non_empty_columns
    # 打开文件选择对话框，并指定文件类型为Excel文件
    file_path = filedialog.askopenfilename(
        filetypes=[("Excel files", "*.xlsx *.xls")]  # 只允许选择Excel文件
    )

    if file_path:
        try:
            # 使用pandas读取Excel文件
            df = pd.read_excel(file_path, sheet_name=int(entry_value01.get()))
            non_empty_columns = filter_non_empty_columns(df.columns.tolist())
            formatted_output = '\n'.join([f"{index}：{column}" for index, column in enumerate(non_empty_columns)])
            headers_string_var.set(formatted_output)
            # print(entry_value.get())
            print("File loaded successfully")
            # 在这里可以添加更多逻辑，例如显示数据或者对数据进行操作
        except Exception as e:
            print(f"Failed to load the Excel file: {e}")
def select_directory():
    global directory
    """ 打开文件夹选择对话框并更新文本框 """
    directory = filedialog.askdirectory()
    if directory:
        # 如果用户选择了文件夹，则更新文本框的内容
        entry_path.delete(0, tk.END)  # 清空当前内容
        entry_path.insert(0, directory)  # 插入新路径
def validate(P):
    """ 验证输入是否为数字 """
    if P.isdigit() or P == "":
        # 如果是数字或空字符串（允许删除操作），返回True
        return True
    else:
        # 否则显示警告并返回False
        messagebox.showwarning("无效输入", "请输入数字")
        return False
def defaultValueEntry(tk, value):
    # 创建一个StringVar变量用于跟踪和设置Entry的值
    entry_value = tk.StringVar()
    entry_value.set(value)
    return entry_value
def is_column_name_empty(name):
    """ 判断给定的列名是否为空或默认未命名 """
    return name.startswith('Unnamed:') or not name.strip()
def filter_non_empty_columns(columns):
    """ 过滤掉空标题的列，并返回新的列表 """
    return [name for name in columns if not is_column_name_empty(name)]
def resource_path(relative_path):
    """ 获取静态资源的正确路径 """
    try:
        # PyInstaller 创建的临时文件夹，或当脚本以 --onefile 模式打包时的系统临时文件夹
        base_path = sys._MEIPASS
    except Exception:
        # 如果是开发环境下的正常路径
        base_path = os.path.abspath(".")

    return os.path.join(base_path, relative_path)
def outputJSON():
    if not non_empty_columns:
        return
    # 使用函数获取资源路径
    template_deck_object_path = resource_path('templateDeckObject.json')
    template_deck_path = resource_path('templateDeck.json')
    with open(template_deck_object_path, 'r', encoding='utf_8_sig') as file:
        data = json.load(file)

    with open(template_deck_path, 'r', encoding='utf_8_sig') as file:
        dataDeck = json.load(file)
    deckIds = dataDeck["ObjectStates"][0]["DeckIDs"]
    customDeck = dataDeck["ObjectStates"][0]["CustomDeck"]
    containedObjects = dataDeck["ObjectStates"][0]["ContainedObjects"]
    deckObjectId = 20
    excelFormatValue = []
    for i in range(min(int(entry_value.get()), df.values.shape[0])):
        deckObjectId += 1
        continueFlag = 0
        for index, excelHeader in enumerate(df.columns.tolist()):
            if is_column_name_empty(excelHeader):
                continue
            if excelHeader.find("链接") > 0:
                faceURLEach = df.values[i][index]
                if pandas.isna(faceURLEach):
                    continueFlag = 1
            excelFormatValue.append(df.values[i][index])

        if continueFlag == 1:
            continue
        nickNameFinal = text_box.get("1.0", tk.END).format(*excelFormatValue)
        excelFormatValue = []
        # 保存json文件
        dateCopy = deepcopy(data)

        dateCopy['GUID'] = generate_random_string()
        dateCopy['Nickname'] = nickNameFinal
        dateCopy['CustomDeck']['10']['FaceURL'] = faceURLEach
        dateCopy['CustomDeck']['10']['BackURL'] = backURLTemplate
        dateCopy['CustomDeck'][str(deckObjectId)] = dateCopy['CustomDeck']['10']
        del dateCopy['CustomDeck']['10']

        customDeck[str(deckObjectId)] = dateCopy['CustomDeck'][str(deckObjectId)]
        deckIds.append(deckObjectId * 100 + 1)
        containedObjects.append(dateCopy)
    # 构造完整路径并保存JSON文件
    output_file_path = os.path.join(directory, "卡组堆.json")
    with open(output_file_path, "w") as file:
        json.dump(dataDeck, file)

# 创建主窗口
root = tk.Tk()
root.title("Select Excel File")
root.geometry('600x700')

# 创建一个Frame以容纳Label和Entry在同一行
frame = tk.Frame(root)
frame.pack(padx=10, pady=10)
label = tk.Label(frame, text="最大数据行数:")
label.pack(side=tk.LEFT, padx=(0, 5))  # 在左侧添加标签，并与Entry之间留一点间距
vcmd = (root.register(validate), '%P')
entry_value = defaultValueEntry(tk, "66")
entry = tk.Entry(frame, textvariable=entry_value, validate="key", validatecommand=vcmd)
entry.pack(side=tk.LEFT)

# 创建一个Frame以容纳Label和Entry在同一行
frame01 = tk.Frame(root)
frame01.pack(padx=10, pady=10)
label01 = tk.Label(frame01, text="读取表索引:")
label01.pack(side=tk.LEFT, padx=(0, 5))  # 在左侧添加标签，并与Entry之间留一点间距
entry_value01 = defaultValueEntry(tk, "0")
entry01 = tk.Entry(frame01, textvariable=entry_value01, validate="key", validatecommand=vcmd)
entry01.pack(padx=10, pady=10)

# 创建一个Frame以容纳Label和Entry在同一行
frame02 = tk.Frame(root)
frame02.pack(padx=10, pady=10)
label = tk.Label(frame02, text="导出路径:")
label.pack(side=tk.LEFT, padx=(0, 5))  # 在左侧添加标签，并与Entry之间留一点间距
entry_path = tk.Entry(frame02, width=50)
entry_path.pack(side=tk.LEFT, padx=(0, 5))
button_select = tk.Button(frame02, text="选择文件夹", command=select_directory)
button_select.pack(side=tk.LEFT)

# 创建按钮，点击后弹出文件选择对话框
button = tk.Button(root, text="Choose Excel File", command=select_excel_file)
button.pack()

# 读取到的非空标题文本内容
headers_string_var = tk.StringVar()
headers_string_var.set("---读取的非空标题行---")
tk_label_header = tk.Label(root, textvariable=headers_string_var)
tk_label_header.pack(padx=10, pady=10)

# 输出字符串模板
frame03 = tk.Frame(root)
frame03.pack(padx=10, pady=10)
label = tk.Label(frame03, text="输出字符串模板:")
label.pack(side=tk.LEFT, padx=(0, 5))  # 在左侧添加标签，并与Entry之间留一点间距
# 创建一个Text小部件用于多行输入
text_box = tk.Text(frame03, wrap=tk.NONE, width=40, height=10)  # wrap=tk.WORD 表示按单词换行
text_box.pack(padx=10, pady=10)
text_box.insert(tk.END, default_outJson_text)  # 在文本框结尾插入默认文本

button01 = tk.Button(root, text="确定导出", command=outputJSON)
button01.pack()


# 运行应用程序
root.mainloop()